#include "DoOpStack.h"
#include "DevilSemantic.h"

void DoOpStack::ds_pop::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1 = state.getOpStack().pop();
	CRefPtr< _DoObject > obj2;
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;
}

void DoOpStack::ds_exch::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1 = state.getOpStack().pop();
	CRefPtr< _DoObject > obj2 = state.getOpStack().pop();
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;

	state.getOpStack().push(obj1);
	state.getOpStack().push(obj2);
}

void DoOpStack::ds_dup::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1 = state.getOpStack().top(0);
	CRefPtr< _DoObject > obj2;
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;

	obj2 = _DoObject::clone(obj1);
	state.getOpStack().push(obj2);
}

void DoOpStack::ds_copy::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1 = state.getOpStack().pop();
	CRefPtr< _DoObject > obj2;
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;

	int n = toNumber(obj1)->getInt();
	std::vector< CRefPtr< _DoObject > > list;
	for(int i = n - 1; i >= 0; i--) {
		obj2 = state.getOpStack().top(i);
		obj3 = _DoObject::clone(obj2);
		list.push_back(obj3);
	}
	for(int i = 0; i < n; i++) {
		state.getOpStack().push(list.at(i));
	}
}

bool DoOpStack::ds_copy::match(DevilSemantic &state) const 
{
	if (state.getOpStack().size() < 1)
		return false;
	CRefPtr< _DoObject > obj1 = state.getOpStack().top(0);
	if (obj1->type() == eNumber)
		return true;
	return false;
}

void DoOpStack::ds_index::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1 = state.getOpStack().pop();
	CRefPtr< _DoObject > obj2;
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;
	
	int n = toNumber(obj1)->getInt();
	obj2 = state.getOpStack().top(n);
	obj3 = _DoObject::clone(obj2);
	
	state.getOpStack().push(obj3);
}

void DoOpStack::ds_roll::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1 = state.getOpStack().pop();
	CRefPtr< _DoObject > obj2 = state.getOpStack().pop();
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;
			
	int j = toNumber(obj1)->getInt();
	int n = toNumber(obj2)->getInt();
	if (j >= 0) {
		for(int ii = 0; ii < j; ii++) {
			obj3 = state.getOpStack().pop();
			state.getOpStack().insert(state.getOpStack().size() - n + 1, obj3);
		}
	} else {
		for(int ii = j; ii < 0; ii++) {
			obj3 = state.getOpStack().remove(state.getOpStack().size() - n);
			state.getOpStack().push(obj3);
		}
	}
}

void DoOpStack::ds_clear::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1;
	CRefPtr< _DoObject > obj2;
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;
	CXXTHROW
}

void DoOpStack::ds_count::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1;
	CRefPtr< _DoObject > obj2;
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;
	CXXTHROW
}

void DoOpStack::ds_mark::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1;
	CRefPtr< _DoObject > obj2;
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;
	CXXTHROW
}

void DoOpStack::ds_cleartomark::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1;
	CRefPtr< _DoObject > obj2;
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;
	
	state.getOpStack().clearToMark();
}

void DoOpStack::ds_counttomark::execute(DevilSemantic &state)
{
	CRefPtr< _DoObject > obj1;
	CRefPtr< _DoObject > obj2;
	CRefPtr< _DoObject > obj3;
	CRefPtr< _DoObject > obj4;
	CRefPtr< _DoObject > obj5;
	CXXTHROW
}

